package com.xinzhidi.web.balancedview.service;


import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.xinzhidi.common.constant.AgreementConstants;
import com.xinzhidi.web.balancedview.domain.po.BalanceLineChartPo;
import com.xinzhidi.web.balancedview.domain.po.BalancedViewPo;
import com.xinzhidi.web.balancedview.domain.vo.BalanceLineChartVo;
import com.xinzhidi.web.balancedview.domain.vo.BalancedBuildVo;
import com.xinzhidi.web.balancedview.domain.vo.BalancedViewVo;
import com.xinzhidi.web.balancedview.domain.vo.BuildViewVo;
import com.xinzhidi.web.balancedview.mapper.BalancedViewMapper;
import com.xinzhidi.web.build.domain.BuildUnit;
import com.xinzhidi.web.build.domain.vo.BuildUnitVo;
import com.xinzhidi.web.build.service.IBuildUnitService;
import com.xinzhidi.web.ctw.domain.entity.HouseholdTemperature;
import com.xinzhidi.web.ctw.service.CtwService;
import com.xinzhidi.web.ctw.service.HouseholdTemperatureService;
import com.xinzhidi.web.equipment.domain.Equipment;
import com.xinzhidi.web.equipment.domain.po.EquipmentPo;
import com.xinzhidi.web.equipment.domain.vo.EquipmentInfoVo;
import com.xinzhidi.web.equipment.domain.vo.EquipmentTemperatureVo;
import com.xinzhidi.web.equipment.service.EquipmentService;
import com.xinzhidi.web.house.domain.Household;
import com.xinzhidi.web.house.domain.vo.HouseholdInfoVo;
import com.xinzhidi.web.house.domain.vo.HouseholdVo;
import com.xinzhidi.web.house.service.IHouseholdService;
import com.xinzhidi.web.netty.entity.dto.AgreementHeatListDto;
import com.xinzhidi.web.netty.entity.householdHeat.ReadData;
import com.xinzhidi.web.netty.service.AgreementHeatService;
import com.xinzhidi.web.netty.service.AgreementHouseholdValveService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @author cx
 */
@Service
@RequiredArgsConstructor
public class BalancedViewService {

    private final IHouseholdService householdService;

    private final IBuildUnitService buildUnitService;

    private final EquipmentService equipmentService;

    private final AgreementHouseholdValveService agreementHouseholdValveService;

    private final AgreementHeatService agreementHeatService;

    private final BalancedViewMapper viewMapper;

    private final HouseholdTemperatureService householdTemperatureService;

    private final CtwService ctwService;


    /**
     * 单元住户列表
     *
     * @param viewPo
     * @return
     */
    public BalancedViewVo getUnitHousehold(BalancedViewPo viewPo) {

        BalancedViewVo viewVo = new BalancedViewVo();
        viewVo.setPlotId(viewPo.getPlotId());
        LambdaQueryWrapper<BuildUnit> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(BuildUnit::getLotId, viewPo.getPlotId())
                .eq(BuildUnit::getBuildId, viewPo.getBuildId());
        List<BuildUnit> unitList = buildUnitService.list(wrapper);
        if (CollectionUtils.isEmpty(unitList)) {
            return viewVo;
        }
        List<BuildUnitVo> buildUnitVoList = Lists.newArrayList();
        unitList.forEach(unitVo -> {
            BuildUnitVo buildUnitVo = new BuildUnitVo();
            buildUnitVo.setId(unitVo.getId());
            buildUnitVo.setUnitName(unitVo.getUnitName());
            buildUnitVo.setFloorNumber(unitVo.getFloorNumber());
            buildUnitVoList.add(buildUnitVo);
        });


        List<Long> unitIds = buildUnitVoList.stream().map(BuildUnitVo::getId).collect(java.util.stream.Collectors.toList());
        LambdaQueryWrapper<Household> householdWrapper = Wrappers.lambdaQuery();
        householdWrapper.in(Household::getUnit, unitIds);
        List<Household> householdList = householdService.list(householdWrapper);
        List<HouseholdVo> householdVoList = Lists.newArrayList();

        //初始化线程数量
        CountDownLatch countDownLatch = ThreadUtil.newCountDownLatch(householdList.size());
        for(Household vo : householdList){
            List<HouseholdVo> householdnewVoList = householdVoList;
            ThreadUtil.execute(() -> {
                HouseholdVo householdVo = new HouseholdVo();
                householdVo.setId(vo.getId());
                householdVo.setUnit(vo.getUnit());
                householdVo.setFloor(vo.getFloor());
                householdVo.setHouseNumber(vo.getHouseNumber());
                Equipment equipment = equipmentService.getOne(
                        Wrappers.<Equipment>lambdaQuery()
                                .eq(Equipment::getHouseholdId, vo.getId())
                                .and((w) -> {
                                    w.eq(Equipment::getProtocolType, AgreementConstants.AgreementType.HOUSEHOLD_VALVE)
                                            .or().eq(Equipment::getProtocolType, AgreementConstants.AgreementType.SEAHORSE_VALVE_METER);
                                })
                );

                householdVo.setStatus(equipment == null ? 0 : equipment.getStatus());
                householdVo.setValveOpen(vo.getValveOpen());
                //获取室温设备
                EquipmentTemperatureVo temperatureEquipment = equipmentService.getTemperatureEquipment(vo.getId());
                if (temperatureEquipment != null) {
                    householdVo.setDeviceStatus(temperatureEquipment.getStatus());
                    householdVo.setRoomTemperature(temperatureEquipment.getTemperature());
                }
                householdnewVoList.add(householdVo);
                //调用线程计数器-1
                countDownLatch.countDown();
            });
            householdVoList.addAll(householdnewVoList);
        }
        //唤醒主线程
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        for(BuildUnitVo unitVo: buildUnitVoList){
            unitVo.setHouseholdVoList(householdVoList.stream().filter(vo -> vo.getUnit().equals(unitVo.getId())).collect(java.util.stream.Collectors.toList()));
        }
        viewVo.setBuildUnitVoList(buildUnitVoList);
        return viewVo;
    }

    public ReadData getHouseholdHeatData(BalancedViewPo viewPo) {
        AgreementHeatListDto dto = new AgreementHeatListDto();
        dto.setHouseholdId(viewPo.getHouseholdId());
        dto.setInstructType("1");
        dto.setProtocolType(AgreementConstants.AgreementType.HOUSEHOLD_HEAT_METER);
        ReadData readData = agreementHeatService.getHouseholdHeatData(dto);

        Household h = householdService.getById(viewPo.getHouseholdId());
        if (readData == null) {
            readData = new ReadData();
        }
        readData.setVelocityFlow(h.getVelocityFlow());
        readData.setThermalPower(h.getThermalPower());
        readData.setWaterSupplyTemperature(h.getWaterSupplyTemperature());
        readData.setReturnWaterTemperature(h.getReturnWaterTemperature());
        readData.setTotalFlow(h.getTotalFlow());
        readData.setCurrentHeatOrCold(h.getCurrentHeatOrCold());
        return readData;
    }

    public List<EquipmentInfoVo> getHouseholdEquipment(BalancedViewPo viewPo) {
        EquipmentPo equipmentPo = new EquipmentPo();
        equipmentPo.setHouseholdId(viewPo.getHouseholdId());
        List<EquipmentInfoVo> list = equipmentService.getEquipmentList(equipmentPo);
        return list;
    }

    /**
     * 住户基本数据
     *
     * @param householdId 住户id
     * @return java.lang.String
     * @author cx
     * @date 2023/6/27 11:53
     **/
    public HouseholdInfoVo getHouseholdInf(Long householdId) {
        return householdService.selectHouseholdById(householdId);
    }

    /**
     * 获取楼栋列表
     *
     * @param viewPo
     * @return
     */
    public BuildViewVo getBuildList(BalancedViewPo viewPo) {
        BuildViewVo buildViewVo = viewMapper.getPlotVo(viewPo);
        if (buildViewVo == null) {
            return buildViewVo;
        }
        List<BalancedBuildVo> balancedBuildVoList = viewMapper.getBuildList(viewPo);
        if (CollectionUtils.isNotEmpty(balancedBuildVoList)) {
            buildViewVo.setBalancedBuildVoList(balancedBuildVoList);
        } else {
            buildViewVo.setBalancedBuildVoList(Lists.newArrayList());
        }

        return buildViewVo;
    }

    public String getHouseholdValveOpen(Long householdId) {
//        String valveOpen = "";
//        AgreementHouseholdValveListDto dto = new AgreementHouseholdValveListDto();
//        dto.setHouseholdId(householdId);
//        dto.setInstructType("2");
//        ValveDataRead valveDataRead = agreementHouseholdValveService.getValveDataRead(dto);
//        if (valveDataRead != null) {
//            valveOpen = valveDataRead.getValveOpen();
//        }
        Household h = householdService.getById(householdId);
        String valveOpen = h.getValveOpen() + "";
        return valveOpen;
    }

    public HouseholdTemperature updateTemperature(Long householdId) {
        LambdaQueryWrapper<HouseholdTemperature> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(HouseholdTemperature::getHouseholdId, householdId);
        HouseholdTemperature temperature = householdTemperatureService.getOne(wrapper);
//        return householdTemperatureService.getTemperatureByHouseholdId(householdId);
        return temperature;
    }

    public List<BalanceLineChartVo> LineChart(BalanceLineChartPo chartPo) {
        List<BalanceLineChartVo> list = Lists.newArrayList();
        String filedName = chartPo.getDataType() == 1 ? "\'$.totalFlow\'" : "\'$.currentHeatOrCold\'";

        chartPo.setFiledName(filedName);
        if (chartPo.getSearchType() == 1) {
            //查询当天数据
            list = viewMapper.currentLineChart(chartPo);
        } else if (chartPo.getSearchType() == 2) {
            //查询近7日数据
            list = viewMapper.lastSevenDayLineChart(chartPo);
        } else if (chartPo.getSearchType() == 3) {
            chartPo.setMonth(6);
            //查询近半年数据
            list = viewMapper.lastMonthLineChart(chartPo);
        } else {
            chartPo.setMonth(12);
            list = viewMapper.lastMonthLineChart(chartPo);
        }

        return list;
    }
}
